home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
strategy
/
vga_card.000
/
vga_cardgames-1.3.1.tar
/
vga_cardgames
/
solitaire.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-25
|
5KB
|
266 lines
/*
* Solitaire game (name unknown)
*
* Copyright (C) Evan Harris, 1991, 1994
*
* Permission is granted to freely redistribute and modify this code,
* providing the author(s) get credit for having written it.
*/
#include "solitaire.h"
#include <stdlib.h>
#define U_MOVE 1
#define U_MOVE_EXPOSE 3
struct undo {
unsigned char type;
unsigned char card;
short from;
struct undo *next;
};
unsigned char column[COLUMNS]; /* First card of column */
short cards[NUMCARDS]; /* Positions of cards */
unsigned char next[NUMCARDS]; /* Card underneath */
unsigned char hidden[NUMCARDS]; /* Cards which are face down */
struct undo *undoinfo = NULL;
void main(int argc, char **argv)
{
short cmd, dest;
InitDisplay(argc, argv);
InitRandom(NEW);
Deal();
for (;;) {
cmd = GetCmd();
if (cmd == QUIT) {
EndDisplay();
exit(0);
}
if (cmd == NEWGAME) {
InitRandom(NEW);
Deal();
}
else if (cmd == RESTART) {
InitRandom(LAST);
Deal();
}
else if (cmd == UNDO) {
Undo();
}
else if (ISCARD(cmd)) {
dest = FindDest((unsigned char)cmd);
if (dest != NOPOSN)
MakeMove((unsigned char)cmd, dest);
}
}
/* Never reached */
}
void Deal()
{
unsigned char i, j;
short r;
/* Initialise the deck */
for (i = 0; i < NUMCARDS; i++) {
cards[i] = NOPOSN;
next[i] = NOCARD;
}
/* Deal the deck */
for (i = 0; i < NUMCARDS; i++) {
r = Random(NUMCARDS - i);
for (j = 0; j < NUMCARDS && r >= 0; j++) {
if (cards[j] == NOPOSN)
r--;
}
r = j - 1;
cards[r] = POSN(i % 7, i / 7);
if (i / 7 == 0)
column[i % 7] = r;
else {
for (j = 0; cards[j] != POSN(i % 7, i / 7 - 1); j++)
;
next[j] = r;
}
if ((i / 7 <= 2) && (i % 7 >= 4))
hidden[r] = 1;
else
hidden[r] = 0;
}
for (i = 0; i < 7; i++)
DisplayColumn((short)i);
return;
}
short FindDest(unsigned char card)
{
unsigned char i, c;
if (TYPE(card) == KING) {
if (ROW(cards[card]) == 0)
return NOPOSN;
for (i = 0; i < COLUMNS; i++)
if (column[i] == NOCARD)
return (short)POSN(i, 0);
}
else {
for (i = 0; i < COLUMNS; i++)
if (i != COL(cards[card])) {
c = column[i];
while (next[c] != NOCARD)
c = next[c];
if (c == CARD(SUIT(card), TYPE(card) + 1))
return (short)POSN(COL(cards[c]), ROW(cards[c]) + 1);
}
}
return NOPOSN;
}
void MakeMove(unsigned char card, short dest)
{
short col, row, oldcol;
unsigned char c, i;
unsigned char h = 0;
col = COL(dest);
row = ROW(dest);
oldcol = -1;
for (i = 0; oldcol == -1 && i < COLUMNS; i++) {
if (column[i] == card) {
column[i] = NOCARD;
oldcol = i;
}
}
for (i = 0; oldcol == -1 && i < NUMCARDS; i++) {
if (next[i] == card) {
if (hidden[i]) {
hidden[i] = 0;
h = 1;
}
next[i] = NOCARD;
oldcol = COL(cards[i]);
}
}
if (h)
AddUndo(U_MOVE_EXPOSE, card, cards[card]);
else
AddUndo(U_MOVE, card, cards[card]);
if (row > 0) {
c = column[col];
while (next[c] != NOCARD)
c = next[c];
next[c] = card;
}
else
column[col] = card;
while (card != NOCARD) {
cards[card] = POSN(col, row++);
card = next[card];
}
DisplayColumn(oldcol);
DisplayColumn(col);
return;
}
void AddUndo(unsigned char type, unsigned char card, short from)
{
struct undo *undo;
undo = (struct undo *)malloc(sizeof(struct undo));
undo->type = type;
undo->card = card;
undo->from = from;
undo->next = undoinfo;
undoinfo = undo;
return;
}
void Undo()
{
struct undo *undo = undoinfo;
if (undo == NULL)
return;
switch (undo->type) {
case U_MOVE:
UndoMove(undo->card, (short)COL(undo->from), 0);
break;
case U_MOVE_EXPOSE:
UndoMove(undo->card, (short)COL(undo->from), 1);
break;
}
undoinfo = undoinfo->next;
free(undo);
return;
}
void UndoMove(unsigned char card, short col, unsigned char expose)
{
unsigned char c, row;
short oldcol;
oldcol = COL(cards[card]);
c = column[oldcol];
if (c == card) {
column[oldcol] = NOCARD;
} else {
while (next[c] != card)
c = next[c];
next[c] = NOCARD;
}
c = column[col];
row = 0;
if (c == NOCARD) {
column[col] = card;
cards[card] = POSN(col, row);
c = next[card];
} else {
while (next[c] != NOCARD) {
c = next[c];
row++;
}
if (expose)
hidden[c] = 1;
next[c] = card;
cards[card] = POSN(col, ++row);
c = next[card];
}
while (c != NOCARD) {
cards[c] = POSN(col, ++row);
c = next[c];
}
DisplayColumn(oldcol);
DisplayColumn(col);
return;
}